package cn.dxs.adt.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.text.SimpleDateFormat;
import java.util.Date;

import cn.dxs.adt.R;
import cn.dxs.adt.utils.QRCodeUtil;

public class CokePoster extends View {

    // 手势操作相关
    private PointF startPoint = new PointF();//PointF(浮点对)
    private int mode = 0;//确定是放大还是缩小
    private static final int DRAG = 1;//拖拉模式
    private static final int ZOOM = 2;//缩放模式
    private float startDis;//开始距离

    private Paint mPaint = new Paint();
    private TextPaint mTextPaint = new TextPaint();
    private RectF mRectF = new RectF(15, 15, 1065, 1715);//背景色块绘制
    private Canvas mCanvas;
    private Rect dst = new Rect(15, 15, 1065, 1065);//图片绘制

    private Bitmap mTopImgBitmap;
    private Rect mTopImgRect = new Rect();
    private Bitmap mQRCodeBitmap;
    private Bitmap mOutBitmap;
    private String mStr_content;
    private String mStr_mpName;
    private float mContentFontSize = 45.0f;//主体内容字体大小
    private float mContentLineHeight = 1.0f;//主体内容行高
    private long mDate;
    private String mDateDay;
    private String mDateWeek;
    private String mDateYearMonth;

    public CokePoster(Context context) {
        super(context);
        init();
    }

    public CokePoster(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CokePoster(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public CokePoster(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        mTopImgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.father);
        int width = mTopImgBitmap.getWidth();
        int height = mTopImgBitmap.getHeight();
        int size = width < height ? width : height;
        mTopImgRect = new Rect(0, 0, size, size);

        mQRCodeBitmap = QRCodeUtil.createQRCodeBitmap("小可乐猪🐷开心的一天^_^🐖！", 220, 220);
        mStr_content = "别因为一次失败，就放弃你原先所要达到的目的。\nDo not, for one repulse, give up the purpose that you resolved to effect.";
        mStr_mpName = "🐷小可乐猪🐷";
        mOutBitmap = Bitmap.createBitmap(1080, 1730, Bitmap.Config.ARGB_8888);
        mDate = System.currentTimeMillis();
        onDate();
    }

    public void setTopImg(Bitmap bitmap) {
        if (bitmap == null) return;
        this.mTopImgBitmap = bitmap;
        int width = mTopImgBitmap.getWidth();
        int height = mTopImgBitmap.getHeight();
        int size = width < height ? width : height;
        mTopImgRect.set(0, 0, size, size);
        postInvalidate();
    }

    public void setImgQRcode(Bitmap bitmap) {
        if (bitmap == null) return;
        // 根据外部调用方传递宽高，计算缩放比，生成最终二维码
        float scaleWidth = 220.0f / bitmap.getWidth();
        float scaleHeight = 220.0f / bitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        this.mQRCodeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
        postInvalidate();
    }

    public void setContent(String str) {
        if (TextUtils.isEmpty(str)) return;
        this.mStr_content = str;
        postInvalidate();
    }

    public void setTxtQRcode(String str) {
        if (TextUtils.isEmpty(str)) return;
        this.mQRCodeBitmap = QRCodeUtil.createQRCodeBitmap(str, 220, 220);
        postInvalidate();
    }

    public void setMpName(String str) {
        if (TextUtils.isEmpty(str)) return;
        this.mStr_mpName = str;
        postInvalidate();
    }

    public void setContentFontSize(float size) {
        this.mContentFontSize += size;
        postInvalidate();
    }

    public void setContentLineHeight(float lineHeight) {
        this.mContentLineHeight += lineHeight;
        postInvalidate();
    }

    public void setDate(int date) {
        long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
        this.mDate += (date * nd);
        onDate();
        postInvalidate();
    }

    private void onDate() {
        SimpleDateFormat day = new SimpleDateFormat("dd");
        SimpleDateFormat week = new SimpleDateFormat("EE");
        SimpleDateFormat yearMonth = new SimpleDateFormat("MM / yyyy");
        Date date = new Date(mDate);
        mDateYearMonth = yearMonth.format(date);
        mDateDay = day.format(date);
        mDateWeek = week.format(date).replace("周", "星期");
    }

    public Bitmap getBitmap() {
        return mOutBitmap;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        this.mCanvas = canvas;
        onDrawBackground();
        onDrawTopImg();
        onDrawContent();
        onDrawTxtQRcode();
        onDrawMpName();
        onDrawDate();
    }

    private void onDrawBackground() {
        mCanvas.drawColor(Color.parseColor("#ffffff"));

        mPaint.setShader(null);
        mPaint.setColor(Color.parseColor("#f8f9fd"));
        mPaint.setStyle(Paint.Style.FILL);
        mCanvas.drawRect(mRectF, mPaint);
    }

    private void onDrawTopImg() {
        //绘制背景色块，以方便图片的调整(背景色差大，方便眼睛观察，图片完全遮盖了就算调整完美)
        mPaint.setShader(null);
        mPaint.setColor(Color.parseColor("#ff6600"));
        mPaint.setStyle(Paint.Style.FILL);
        mCanvas.drawRect(dst, mPaint);
        mCanvas.drawBitmap(mTopImgBitmap, mTopImgRect, dst, mPaint);
    }

    private void onDrawContent() {
        //绘制主体内容
        mTextPaint.setShader(null);
        mTextPaint.setAntiAlias(true);// 去锯齿
        mTextPaint.setColor(Color.parseColor("#000000"));
        mTextPaint.setTextSize(mContentFontSize);
        /**
         * 1,字符串
         * 2,画笔
         * 3,layout的宽度，字符串超出宽度时自动换行
         * 4,layout的对其方式，有ALIGN_CENTER(居中对齐)， ALIGN_NORMAL(左对齐)， ALIGN_OPPOSITE(右对齐) 三种
         * 5,相对行间距，相对字体大小，1.5f表示行间距为1.5倍的字体高度
         */
        StaticLayout staticLayout = new StaticLayout(mStr_content, mTextPaint, 1025, Layout.Alignment.ALIGN_NORMAL, mContentLineHeight, 0, true);
        mCanvas.save();
        mCanvas.translate(30, 1100);
        staticLayout.draw(mCanvas);
        mCanvas.restore();
    }

    private void onDrawTxtQRcode() {
        mCanvas.drawBitmap(mQRCodeBitmap, 780, 1410, mPaint);
    }

    private void onDrawMpName() {
        //绘制主体内容
        mTextPaint.setShader(null);
        mTextPaint.setAntiAlias(true);// 去锯齿
        mTextPaint.setColor(Color.parseColor("#000000"));
        mTextPaint.setTextSize(45);
        /**
         * 1,字符串
         * 2,画笔
         * 3,layout的宽度，字符串超出宽度时自动换行
         * 4,layout的对其方式，有ALIGN_CENTER(居中对齐)， ALIGN_NORMAL(左对齐)， ALIGN_OPPOSITE(右对齐) 三种
         * 5,相对行间距，相对字体大小，1.5f表示行间距为1.5倍的字体高度
         */
        StaticLayout staticLayout = new StaticLayout(mStr_mpName, mTextPaint, 500, Layout.Alignment.ALIGN_CENTER, 1, 0, true);
        mCanvas.save();
        mCanvas.translate(640, 1645);
        staticLayout.draw(mCanvas);
        mCanvas.restore();
    }

    private void onDrawDate() {
        mPaint.setShader(null);
        mPaint.setAntiAlias(true);// 去锯齿
        mPaint.setColor(Color.parseColor("#000000"));
        mPaint.setTextSize(45);
        mPaint.setTextAlign(Paint.Align.LEFT);
        mCanvas.drawText("D A T E", 40, 1530, mPaint);

        mPaint.setTextSize(180);
        mCanvas.drawText(mDateDay, 30, 1690, mPaint);

        mPaint.setTextSize(45);
        mCanvas.drawText(mDateWeek, 260, 1630, mPaint);
        mCanvas.drawText(mDateYearMonth, 260, 1690, mPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        boolean result = false;
        //判断事件的类型
        //得到低八位才能获取动作，所以要屏蔽高八位(通过与运算&255)
        //ACTION_MASK就是一个常量，代表255
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN://手指下压
                mode = DRAG;
//                currentMatrix.set(mIv_pic.getImageMatrix());//记录ImageView当前的移动位置
                startPoint.set(event.getX(), event.getY());
                float x = event.getX();
                float y = event.getY();
                if (0 < x && x < 1080 && 0 < y && y < 1065) {
                    result = true;
                }
                break;
            case MotionEvent.ACTION_MOVE://手指在屏幕移动，该事件会不断被调用
                if (mode == DRAG) {//拖拉模式
                    mTopImgRect.offset((int) (startPoint.x - event.getX()), (int) (startPoint.y - event.getY()));
                    startPoint.set(event.getX(), event.getY());
                } else if (mode == ZOOM) {//缩放模式
                    float endDis = distance(event);//结束距离
                    if (endDis > 10f) {//防止不规则手指触碰
                        int s = (int) (endDis - startDis);
                        int left = mTopImgRect.left + s;
                        int top = mTopImgRect.top + s;
                        int right = mTopImgRect.right - s;
                        int bottom = mTopImgRect.bottom - s;
                        mTopImgRect.set(left, top, right, bottom);
                        startDis = endDis;
                    }
                }
                break;
            case MotionEvent.ACTION_UP://手指离开屏幕
            case MotionEvent.ACTION_POINTER_UP://当屏幕上已经有手指离开屏幕，屏幕上还有一个手指，就会触发这个事件
                mode = 0;
                break;
            case MotionEvent.ACTION_POINTER_DOWN://当屏幕上已经有触点(手指)，再有一个手指按下屏幕，就会触发这个事件
                mode = ZOOM;
                startDis = distance(event);
                break;
        }
        postInvalidate();
        return result;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                getParent().getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_UP:
                getParent().getParent().requestDisallowInterceptTouchEvent(false);
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 计算两点之间的距离(勾股定理)
     * @param event
     * @return
     */
    public float distance(MotionEvent event) {
        float dx = event.getX(1) - event.getX(0);
        float dy = event.getY(1) - event.getY(0);
        return (float) Math.sqrt(dx * dx + dy * dy);
    }
}
